﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using Kangaroo.Model;
using Kangaroo.Model.Tests;
using System.Security.Cryptography;

namespace Kangaroo.PDTableDataGen
{
    public enum DatabaseType
    {
        Oracle,
        SqlServer
    }
    class Program
    {
        static void Main(string[] args)
        {
           /* SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, @"DELETE FROM PDTable");
            SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, @"DELETE FROM ChannelTable");
            SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, @"DELETE FROM AlarmTable");
            */
            var graphData = ReadDataFromFile(@"input\FloatingElectrode1.ssd.csv");

            var prpsGraph = GeneratePrpsGraph(graphData);

            for(var i = 0; i < 2000;i++ )
            {
                CreatePdEntry(prpsGraph, DatabaseType.SqlServer);
            }
        }

        private static byte[] encryptDecryptStr(byte[] bs, byte key)
        {
            for (int i = 0; i < bs.Length; i++)
            {
                bs[i] = (byte)(bs[i] ^ key);
            }
            return bs;
        }


        static Random _random = new Random();

        private static DateTime _dateTime = DateTime.Now.AddHours(-400);
        private static int i = 0;

        private static void CreatePdEntry(byte[] prpsGraph, DatabaseType type)
        {
            var devId = "检测装置1";
            short devChn = 0;
            string equipId = "电力设备4";
            byte equipPhase = 1;
            DateTime pdTime = (_dateTime = _dateTime.AddHours(1));
            float pdMean = (float) _random.NextDouble();
            float pdMax = (float) _random.NextDouble();
            float pdPhase = (i++)/2 == 0 ? _random.Next(5)*5 : 360 - _random.Next(5)*5;
            float pdRep = _random.Next(100) + 50;
            string pdType = "悬浮电极;0.87";
            string pdTypeProb = "pdTypeProb1";
            string pdLoc = "pdLoc1";
            string pdLevel = "pdLevel1";
            string pdFile = "pdFile1";
            long key = 0;

            switch(type)
            {
                case DatabaseType.Oracle:
                    DAL.Oracle.OracleHelper.ConnectionString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=csvm1813410-gu)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)));User Id=system;Password=123456";
                    key = DAL.Oracle.Tests.DalTestHelper.CreateSignal(devId, devChn, equipId, equipPhase,
                        pdTime, pdMean, pdMax, pdPhase, pdRep, pdType,
                        pdTypeProb, pdLoc, pdLevel, pdFile, prpsGraph);
                    Console.WriteLine("Entry created in database. Entry key is {0}", key);
                    break;
                case DatabaseType.SqlServer:
                    DAL.SqlServer.SqlHelper.ConnectionString = @"Data Source=.\sqlexpress;Initial Catalog=Kangaroo;Integrated Security=True;";
                    key = DAL.SqlServer.Tests.DalTestHelper.CreateSignal(devId, devChn, equipId, equipPhase,
                        pdTime, pdMean, pdMax, pdPhase, pdRep, pdType,
                        pdTypeProb, pdLoc, pdLevel, pdFile, prpsGraph);
                    Console.WriteLine("Entry created in database. Entry key is {0}", key);
                    break;
            }
            
        }

        

        private static byte[] GeneratePrpsGraph(float[] graphData, bool engrypt = true)
        {
            var memory = new MemoryStream();
            var writer = new BinaryWriter(memory);
            var graphType = PrpsGraph.PrpsHeader.GraphType.Prps;
            var xMax = 60;
            var yMax = 50;

            writer.Write((UInt32)graphType);
            writer.Write((UInt16)xMax);
            writer.Write((UInt16)yMax);

            const int headerSize = 32;
            memory.SetLength(headerSize);
            memory.Seek(0, SeekOrigin.End);

            int key = 221;
            if (engrypt)
            {
                foreach (var data in graphData)
                {
                    writer.Write(encryptDecryptStr(BitConverter.GetBytes(data), (byte)key));
                }
            }
            else
            {
                foreach (var data in graphData)
                {
                    writer.Write(data);
                }

            }

            writer.Flush();

            var rawData = memory.ToArray();
            Console.WriteLine("PRPSGraph data generated.");
            return rawData;
        }

        private static float[] ReadDataFromFile(string inputFile)
        {
            Console.WriteLine("Reading data from file: {0}", inputFile);

            var graphData =
                File.ReadAllText(inputFile).Split(new[] { '\n', '\r', ',' }, StringSplitOptions.RemoveEmptyEntries).Select( s => 
                    float.Parse(s) / 200).ToArray();
            Console.WriteLine("Successfully read {0} data points.", graphData.Length);
            return graphData;
        }
    }
}
